import { locations } from "../../../gpu/locations";
/**
 *标准材质片元着色器
 * @class
 *  
 */
let StandardMaterial = /* wgsl */ `
    #include <Camera>
    #include <StandardMaterial_def>
    #include <Func>
    const M_PI:f32=3.141592653589793;//常量PI
    const EPSILON:f32= 1e-6;
    override GAMM:f32=1.8;  
  
fn Mat4ToMat3(transformMat4:mat4x4<f32>)->mat3x3<f32>{
  var uvm=mat3x3<f32>(transformMat4[0][0],transformMat4[0][1],transformMat4[0][2],
    transformMat4[0][3],transformMat4[1][0],transformMat4[1][1],
    transformMat4[1][2],transformMat4[1][3],transformMat4[2][0],
    );
   return  uvm;
}
fn pixelToWorld(pixel:f32)->f32{
  return (pixel/camera.viewport.y)*camera.dist*2.309401076758503;
}
fn getLineUV(uvWidthFactor:vec4<f32>, lineWidth:f32, map_uvPixel: f32)->vec3<f32>{
  var uv:vec3<f32>;
  var r:vec2<f32>=vec2(.0,.0);
  r=vec2(uvWidthFactor[0]+uvWidthFactor[1]*pixelToWorld(lineWidth), uvWidthFactor[2]+uvWidthFactor[3]*pixelToWorld(lineWidth));
  r=vec2(r[0]/pixelToWorld(map_uvPixel), r[1]);
  #if ~{def.map_uvOffset}
  uv=vec3<f32>(r[0] + map_uvOffset[0], r[1] + map_uvOffset[1], 1.0);
  #else
  uv=vec3<f32>(r[0], r[1], 1.0);
  #endif
  return uv;
}

fn getNormalUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    #if ~{def.texCood0||def.texCood1}
     uv=vec3<f32>(input.texCood~{def.normalMapUvIndex ? def.normalMapUvIndex : "0"}, 1.0);
    #else
     uv=vec3<f32>(1.0);
     #endif
  #endif
  #if ~{def.normalMapUVTransform}
    var uvm=Mat4ToMat3(normalMap_uvTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}

#if ~{def.map}
fn getMapUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
  uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
  #if ~{def.texCood0}
  uv=vec3<f32>(input.texCood~{def.mapUvIndex ? def.mapUvIndex : "0"}, 1.0);
  #else
  uv=vec3<f32>(0.5);
  #endif 
  #if ~{def.map_uvOffset}
  uv = vec3(uv[0] + map_uvOffset[0], uv[1] + map_uvOffset[1], uv[2]);
  #endif
  #endif 

  #if ~{def.mapUVTransform}
  var uvm=Mat4ToMat3(map_uvTransform);
  uv =uvm*uv ;
  #endif 

  return uv.xy;
}
#endif
#if ~{def.metRougMap}
fn getMetallicRoughnessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.metRougMapUvIndex ? def.metRougMapUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.metRougMapUVTransform}
    var uvm=Mat4ToMat3(metRougMapUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_Clearcoat}
fn getClearcoatUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_ClearcoatUvIndex ? def.u_ClearcoatUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_ClearcoatUvTransform}
    var uvm=Mat4ToMat3(u_ClearcoatUvTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_ClearcoatRoughness}
fn getClearcoatRoughnessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_ClearcoatRoughnessUvIndex ? def.u_ClearcoatRoughnessUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_ClearcoatRoughnessUVTransform}
    var uvm=Mat4ToMat3(u_ClearcoatRoughnessUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_ClearcoatNormal}
fn getClearcoatNormalUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_ClearcoatNormalUvIndex ? def.u_ClearcoatNormalUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_ClearcoatNormalUVTransform}
    var uvm=Mat4ToMat3(u_ClearcoatNormalUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
fn getClearcoatNormal(normalInfo:NormalInfo)->vec2<f32>{
  #if ~{def.u_ClearcoatNormal}
    var n = textureSample (u_ClearcoatNormal,u_ClearcoatNormalSampler,getClearcoatNormalUV()).rgb * 2.0 - vec3(1.0);
    n *= vec3(u_ClearcoatNormalScale, u_ClearcoatNormalScale, 1.0);
    n = mat3(normalInfo.t, normalInfo.b, normalInfo.ng) * normalize(n);
    return n;
  #else
     return normalInfo.ng;
  #endif
}
#endif


#if ~{def.aoMap}
fn getOcclusionUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.aoMapUvIndex ? def.aoMapUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.aoMapUVTransform}
    var uvm=Mat4ToMat3(aoMap_uvTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.emissiveMap}
fn getEmissiveUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.emissiveMapUvIndex ? def.emissiveMapUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.emissiveMapUVTransform}
    var uvm=Mat4ToMat3(emissiveMap_uvTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.uSG_Diffuse}
fn getDiffuseUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.uSG_DiffuseUvIndex ? def.uSG_DiffuseUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.uSG_DiffuseUVTransform}
    var uvm=Mat4ToMat3(uSG_DiffuseUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.uSG_SpecularGlossiness}
fn getSpecularGlossinessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.uSG_SpecularGlossinessUvIndex ? def.uSG_SpecularGlossinessUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.uSG_DiffuseUVTransform}
    var uvm=Mat4ToMat3(uSG_DiffuseUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_SheenColor}
fn getSheenColorUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.uu_SheenColorUvIndex ? def.u_SheenColorUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_SheenColorUVTransform}
    var uvm=Mat4ToMat3(u_SheenColorUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_SheenRoughness}
fn getSheenRoughnessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_SheenRoughnessUvIndex ? def.u_SheenRoughnessUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_SheenRoughnessUvTransform}
    var uvm=Mat4ToMat3(u_SheenRoughnessUvTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_Specular}
fn getSpecularUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_SpecularUvIndex ? def.u_SpecularUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_SpecularUVTransform}
    var uvm=Mat4ToMat3(u_SpecularUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_SpecularColor}
fn getSpecularColorUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_SpecularColorUvIndex ? def.u_SpecularColorUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_SpecularColorUVTransform}
    var uvm=Mat4ToMat3(u_SpecularColorUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_Transmission}
fn getTransmissionUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_TransmissionUvIndex ? def.u_TransmissionUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_TransmissionUVTransform}
    var uvm=Mat4ToMat3(u_TransmissionUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_Thickness}
fn getThicknessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_ThicknessUvIndex ? def.u_ThicknessUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_ThicknessUVTransform}
    var uvm=Mat4ToMat3(u_ThicknessUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_Iridescence}
fn getIridescenceUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_IridescenceUvIndex ? def.u_IridescenceUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_IridescenceUVTransform}
    var uvm=Mat4ToMat3(u_IridescenceUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_IridescenceThickness}
fn getIridescenceThicknessUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_IridescenceThicknessUvIndex ? def.u_IridescenceThicknessUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_IridescenceThicknessUVTransform}
    var uvm=Mat4ToMat3(u_IridescenceThicknessUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif

#if ~{def.u_Anisotropy}
fn getAnisotropyUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_AnisotropyUvIndex ? def.u_AnisotropyUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_AnisotropyUVTransform}
    var uvm=Mat4ToMat3(u_AnisotropyUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_DiffuseTransmission}
fn getDiffuseTransmissionUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_DiffuseTransmissionUvIndex ? def.u_DiffuseTransmissionUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_DiffuseTransmissionUVTransform}
    var uvm=Mat4ToMat3(u_DiffuseTransmissionUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif
#if ~{def.u_DiffuseTransmissionColor}
fn getDiffuseTransmissionColorUV(input:Input)->vec2<f32>{
  var uv:vec3<f32>;
  #if ~{def.uvWidthFactor && def.lineWidth && def.map_uvPixel}
    uv=getLineUV(input.uvWidthFactor, lineWidth, map_uvPixel);
  #else
    uv=vec3<f32>(input.texCood~{def.u_DiffuseTransmissionColorUvIndex ? def.u_DiffuseTransmissionColorUvIndex : "0"}, 1.0);
  #endif
  #if ~{def.u_DiffuseTransmissionColorUVTransform}
    var uvm=Mat4ToMat3(u_DiffuseTransmissionColorUVTransform);
    uv =uvm*uv ;
  #endif
  return uv.xy;
}
#endif


struct Input {
  #if ~{def.normal}
  @location(0) normal : vec3<f32>,
  #endif 
  #if ~{def.texCood0}
  @location(1) texCood0 : vec2<f32>,
  #endif
  #if ~{def.texCood1}
  @location(2) texCood1 : vec2<f32>,
  #endif
  #if ~{def.tangent}
  @location(3) tangent:vec3<f32>,
  #endif
  #if ~{def.color}
  @location(4) color : vec4<f32>,
  #endif 
  #if ~{def.uvWidthFactor}
  @location(5) uvWidthFactor : vec4<f32>,
  #endif
  @location(6) fragPosition:vec3<f32>,
  #if ~{def.logarithmicDepth}
  @location(7) flogz : f32,
  #endif
  
  // #if ~{def.lightCastCount}
  // @location(12) shadowPos: vec3<f32>,
  // #endif 
  // #if ~{def.shadowMap2}
  // @location(13) shadowPos2: vec3<f32>,
  // #endif 
  // #if ~{def.shadowMap3}
  // @location(14) shadowPos3: vec3<f32>,
  // #endif 
};
struct Output {
  @location(0) color:vec4<f32>,
  #if ~{def.logarithmicDepth}
    @builtin(frag_depth) fragDepth:f32,
  #endif
  #if ~{def.gBuffer}
    @location(1) worldPos:vec4<f32>,
    @location(2) worldNormal:vec4<f32>,
    #if ~{def.enablePick}
      @location(3) pickColor:vec4<f32>,
    #endif
  #else
    #if ~{def.enablePick}
      @location(1) pickColor:vec4<f32>,
    #endif
  #endif
};
struct MaterialInfo
{
 ior:f32,
 perceptualRoughness:f32,     
 f0_dielectric:vec3<f32>,                     
 alphaRoughness:f32,          
 fresnel_w:f32,
 f90:vec3<f32>,   
 f90_dielectric:vec3<f32>,                 
 metallic:f32,
 baseColor:vec3<f32>,
 sheenRoughnessFactor:f32,
 sheenColorFactor:vec3<f32>,

 clearcoatF0:vec3<f32>,
 clearcoatF90:vec3<f32>,
 clearcoatFactor:f32,
 clearcoatNormal:vec3<f32>,
 clearcoatRoughness:f32,
// KHR_materials_specular 
 specularWeight:f32,
 transmissionFactor:f32,

 thickness:f32,
 attenuationColor:vec3<f32>,
 attenuationDistance:f32,
// KHR_materials_iridescence
 iridescenceFactor:f32,
 iridescenceIor:f32,
 iridescenceThickness:f32,

 diffuseTransmissionFactor:f32,
 diffuseTransmissionColorFactor:vec3<f32>,

   // KHR_materials_anisotropy
 anisotropicT:vec3<f32>,
 anisotropicB:vec3<f32>,
 anisotropyStrength:f32,

  // KHR_materials_dispersion
 dispersion:f32,
};
struct NormalInfo {
   ng:vec3<f32>,   // 几何体法向量
   t:vec3<f32>,    // 几何体切线
   b:vec3<f32>,    // 几何体双切线
   n:vec3<f32>,    // 着色器法向量
   ntex:vec3<f32>, // 从纹理来的法向量
};
#if ~{def.ShadowMap}
fn calculateShadow(light:LightRay,input:Input,bias:f32,depthTexIndex:i32)->f32 {
  let shadowPosTmp = light.lightViewProjMatrix  * vec4<f32>(input.fragPosition, 1.0);
  var shadowPos = shadowPosTmp.xyz / shadowPosTmp.w;
  shadowPos = vec3(
    shadowPos.xy * vec2(0.5, -0.5) + vec2(0.5),
    shadowPos.z
  );
  var inFrustum:bool = shadowPos.x >= 0.0 && shadowPos.x <= 1.0 && shadowPos.y >= 0.0 && shadowPos.y <= 1.0;
  var frustumTest:bool = inFrustum && shadowPos.z <= 1.0;
  var visibility = 1.0;
  let size =f32(textureDimensions(ShadowMap).x);
  if(frustumTest){
    // 阴影锯齿
      for (var y = -2.0; y <= 2.0; y=y+0.5) {
        for (var x = -2.0; x <= 2.0; x=x+0.5) {
          let offset = vec2<f32>(f32(x) / size, f32(y) / size);
          // 取得最近点的深度(使用[0,1]范围下的fragPosLight当坐标)
          var closestDepth  = textureSampleLevel(ShadowMap, ShadowSampler,shadowPos.xy+offset,depthTexIndex,0);
            // 取得当前片段在光源视角下的深度
          var currentDepth = shadowPos.z;
          // 检查当前片段是否在阴影中
          if ((currentDepth - bias ) < closestDepth) {//不在阴影中
            visibility += 1.0 ;
          }else{
            visibility+=light.e3;//shadowIntensity:e3
          }
        }
      }
      visibility /= 81;
    }

  return visibility;
}
#endif
#if ~{def.pointShadow}
var <private> dep:f32;
fn calculateShadowPoint(light:LightRay,input:Input,bias:f32,arrayIndex:u32,n:vec3f)->f32 {
  var sampleOffsetDirections:array<vec3<f32>,20>=array<vec3<f32>, 20>( 
    vec3<f32>( 1,  1,  1), vec3<f32>( 1, -1,  1), vec3<f32>(-1, -1,  1), vec3<f32>(-1,  1,  1), 
    vec3<f32>( 1,  1, -1), vec3<f32>( 1, -1, -1), vec3<f32>(-1, -1, -1), vec3<f32>(-1,  1, -1),
    vec3<f32>( 1,  1,  0), vec3<f32>( 1, -1,  0), vec3<f32>(-1, -1,  0), vec3<f32>(-1,  1,  0),
    vec3<f32>( 1,  0,  1), vec3<f32>(-1,  0,  1), vec3<f32>( 1,  0, -1), vec3<f32>(-1,  0, -1),
    vec3<f32>( 0,  1,  1), vec3<f32>( 0, -1,  1), vec3<f32>( 0, -1, -1), vec3<f32>( 0,  1, -1)
  );
  var shadow = 0.0;
  var samples:u32 = 20;
  // var viewDistance = length(vec3f(0,100,0) - input.fragPosition);
  // var diskRadius = (1.0 + (viewDistance / camera.far)) / 25.0;
  var fragToLight = input.fragPosition - light.position;
  var dir:vec3<f32> = normalize(fragToLight)  ;
  var currentDepth = length(fragToLight);
  // var biasShadow=max(bias*camera.far*(1.0-dot(n,dir)),0.005);
  var depth = textureSampleLevel(shadowMapPoint, shadowSamplerPoint,  dir.xyz, arrayIndex, 0);
  dep= depth;
  depth *= camera.far;
  if ((currentDepth-bias) >depth) {
    shadow = 1.0;
  }
  // for(var i:u32 = 0; i < samples; i++){
  //     var coords:vec3<f32>= fragToLight + sampleOffsetDirections[i] * diskRadius;
  //     // var coords:vec3<f32>= fragToLight ;
  //     var closestDepth = textureSampleLevel(shadowMapPoint,shadowSamplerPoint,coords,arrayIndex,0);
  //     dep= closestDepth;
  //     closestDepth *= 10000;  
  //     // dep=coords;
  //     if(currentDepth - 0.0007 > closestDepth){
  //       shadow += 1.0;
  //     }
  // }
  //  shadow =shadow/f32(samples);
   return shadow;
}
#endif
#if ~{def.ColorAdjust}
  // 1 LinearToneMapping
  fn LinearToneMapping(  color:vec3<f32> )->vec3<f32> {
    return saturate( colorAdjust.ToneMappingExposure * color );
  }
  // 2 ReinhardToneMapping
  fn ReinhardToneMapping( color1:vec3<f32> )->vec3<f32> {
    var color= color1 * colorAdjust.ToneMappingExposure;
    return saturate( color / ( vec3( 1.0 ) + color ) );
  }
  // 3 OptimizedCineonToneMapping
  fn OptimizedCineonToneMapping( color1:vec3<f32> )->vec3<f32> {
    var color= color1 * colorAdjust.ToneMappingExposure;
    color = max( vec3( 0.0 ), color - 0.004 );
    return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
  }
  // 4 RRTAndODTFit
  fn RRTAndODTFit( v:vec3<f32> )->vec3<f32> {
    var a:vec3<f32> = v * ( v + 0.0245786 ) - 0.000090537;
    var b:vec3<f32> = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
    return a / b;

  }
  // 5 ACESFilmicToneMapping
  fn ACESFilmicToneMapping(color1:vec3<f32> )->vec3<f32> {
    // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
    const  ACESInputMat:mat3x3<f32> = mat3x3<f32>(
      vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
      vec3( 0.35458, 0.90834, 0.13383 ),
      vec3( 0.04823, 0.01566, 0.83777 )
    );
    // ODT_SAT => XYZ => D60_2_D65 => sRGB
    const  ACESOutputMat:mat3x3<f32> = mat3x3<f32>(
      vec3(  1.60475, -0.10208, -0.00327 ), // transposed from source
      vec3( -0.53108,  1.10813, -0.07276 ),
      vec3( -0.07367, -0.00605,  1.07602 )
    );
    var color= color1*colorAdjust.ToneMappingExposure / 0.6;
    color = ACESInputMat * color;
    // Apply RRT and ODT
    color = RRTAndODTFit( color );
    color = ACESOutputMat * color;
    // Clamp to [0, 1]
    return saturate( color );
  }
  // 6  CustomToneMapping
  fn CustomToneMapping(color:vec3<f32> )->vec3<f32> { return color; }
#endif
var <private>materialInfo:MaterialInfo;
@fragment 
fn main(input:Input) -> Output {
        var output:Output;
   
        var  material:Material;
        // color
        #if ~{def.uSG_DiffuseFactor}
          material.color=uSG_DiffuseFactor;// Specular Glossiness
        #else
         material.color=baseMaterial.color;//基地色
        #endif
        // SPECULARGLOSSINESS
        #if ~{def.uSG_DiffuseFactor&&def.uSG_Diffuse}
          var correspondUv=getDiffuseUV(input);
          material.color*=textureSample(uSG_Diffuse, uSG_DiffuseSampler, correspondUv);
        #elif ~{def.map}
          var correspondUv=getMapUV(input);
          material.color*=SRGBtoLinear(textureSample(map, map_sampler, correspondUv));
        #endif
        #if ~{def.color}
          material.color*= input.color;
        #endif 
      #if ~{def.enablePick}
        output.pickColor=vec4(baseMaterial.pickColor,1.0);
      #endif
       #if ~{def.alphaCutoff}
          if(material.color.a<alphaCutoff){
            discard;
          }
          //material.color.a = 1.0;//注释掉，解决不支持透明度的bug
       #endif 
       var color:vec3<f32> = vec3(0);
        // 视图向量
        var v:vec3<f32> = normalize(camera.position - input.fragPosition);
        // 法向量
        var normalInfo:NormalInfo;
        #if ~{def.normalMap}
          var UV:vec2<f32>= getNormalUV(input);
          var tangentNormal= textureSample(normalMap,normalMap_sampler, UV).rgb * 2.0 - vec3(1.0);
          var Q1:vec3f  = dpdx(input.fragPosition);
          var Q2:vec3f  = dpdy(input.fragPosition);
          var st1:vec2f = dpdx(UV);
          var st2:vec2f = dpdy(UV);
          #if ~{def.normal}
            var N:vec3f   = normalize(input.normal);
          #else 
            var N:vec3f  = normalize(cross(dpdx(input.fragPosition), dpdy(input.fragPosition)));
          #endif 
          #if ~{def.tangent}
            var T:vec3f   = normalize(input.tangent);
          #else 
            var T:vec3f  = normalize(Q1*st2.y - Q2*st1.y);
          #endif 
          #if ~{def.bitangent}
            var B:vec3f   = normalize(input.bitangent);
          #else 
            var B:vec3f  = -normalize(cross(N, T));
          #endif 
          var TBN:mat3x3f = mat3x3f(T, B, N);
          var n= normalize(TBN * tangentNormal);
        #else  
          #if ~{def.normal}
            var n=normalize(input.normal);
          #else  
            var n=normalize(cross(dpdx(input.fragPosition), dpdy(input.fragPosition)));
          #endif
        #endif 
        normalInfo.n=n;
        if(enableDarker==1.0){
          output.color=vec4(0,0,0,1);
        #if ~{def.gBuffer}
          output.worldPos = vec4<f32>(input.fragPosition.xyz,1.0);
          output.worldNormal = vec4<f32>(n,1.0);
         #endif
         #if ~{def.logarithmicDepth}
         output.fragDepth = log2(input.flogz ) * ~{def.logarithmicDepth} * 0.5;
         #endif
         #if ~{def.enablePick}
         output.pickColor=vec4(baseMaterial.pickColor,1.0);
         #endif
          return output;
        }
         var NdotV:f32 = clampedDot(n, v);
        //  var TdotV:f32 = clampedDot(t, v);
        //  var BdotV:f32 = clampedDot(b, v);
         materialInfo.baseColor = material.color.rgb;
         materialInfo.ior = 1.5;
         materialInfo.f0_dielectric = vec3<f32>(0.04);// 非金属的基础反射率
         materialInfo.specularWeight = 1.0;

         materialInfo.f90 = vec3(1.0);// 掠射角反射率
         materialInfo.f90_dielectric = materialInfo.f90;// 非金属材质继承通用f90值
         // IOR
         #if ~{def.ior}
         materialInfo.f0_dielectric = vec3(pow(( ior - 1.0) /  (ior + 1.0), 2.0));
         materialInfo.ior = ior;
         #endif 
        //  SPECULARGLOSSINESS
         #if ~{def.uSG_DiffuseFactor}
            materialInfo.f0_dielectric = uSG_SpecularFactor;
            materialInfo.perceptualRoughness = uSG_GlossinessFactor;
            #if ~{def.uSG_SpecularGlossiness}
              var correspondUv=getSpecularGlossinessUV(input);
              vec4 sgSample = textureSample(uSG_SpecularGlossiness, uSG_SpecularGlossinessSampler,correspondUv);
              materialInfo.perceptualRoughness *= sgSample.a ; 
              materialInfo.f0_dielectric *= sgSample.rgb; 
            #endif 
            materialInfo.perceptualRoughness = 1.0 - materialInfo.perceptualRoughness; // 1 - glossiness
         #endif
       // METALLICROUGHNESS
       #if ~{def.standardMaterialProperties}
        materialInfo.metallic = baseMaterial.metalness;
        materialInfo.perceptualRoughness = baseMaterial.roughness;
        #if ~{def.metRougMap}
          var mrSample:vec4<f32> = textureSample(metallicRoughnessMap,metallicRoughnessMap_sampler, getMetallicRoughnessUV(input));
          materialInfo.perceptualRoughness *= mrSample.g;
          materialInfo.metallic *= mrSample.b;
        #endif
       #endif
        //SHEEN
        #if ~{def.u_SheenColorFactor}
          materialInfo.sheenColorFactor = u_SheenColorFactor;
          materialInfo.sheenRoughnessFactor = u_SheenRoughnessFactor;
          #if ~{def.u_SheenColor}
              vec4 sheenColorSample = textureSample(u_SheenColor,u_SheenColorSampler,getSheenColorUV() );
              materialInfo.sheenColorFactor *= sheenColorSample.rgb;
          #endif
          #if ~{def.u_SheenRoughness}
              vec4 sheenRoughnessSample = textureSample(u_SheenRoughness,u_SheenRoughnessSampler, getSheenRoughnessUV());
              materialInfo.sheenRoughnessFactor *= sheenRoughnessSample.a;
          #endif
        #endif
        // CLEARCOAT
        #if ~{def.u_ClearcoatFactor}
            materialInfo.clearcoatFactor = u_ClearcoatFactor;
            materialInfo.clearcoatRoughness = u_ClearcoatRoughnessFactor;
            materialInfo.clearcoatF0 = vec3(pow((materialInfo.ior - 1.0) / (materialInfo.ior + 1.0), 2.0));
            materialInfo.clearcoatF90 = vec3(1.0);
            #if ~{def.u_Clearcoat}
              vec4 clearcoatSample = textureSample(u_Clearcoat,u_ClearcoatSampler, getClearcoatUV());
              materialInfo.clearcoatFactor *= clearcoatSample.r;
            #endif
        
            #if ~{def.u_ClearcoatRoughness}
            vec4 clearcoatSampleRoughness = textureSample(u_ClearcoatRoughness,u_ClearcoatRoughnessSampler, getClearcoatRoughnessUV());
            materialInfo.clearcoatRoughness *= clearcoatSampleRoughness.g;
           #endif
        
            materialInfo.clearcoatNormal = getClearcoatNormal(normalInfo);
            materialInfo.clearcoatRoughness = clamp(materialInfo.clearcoatRoughness, 0.0, 1.0);
        #endif
        // SPECULAR
        #if ~{def.specularFactor}
            var  specularTexture:vec4<f32> = vec4(1.0);
            #if ~{def.u_Specular}
                specularTexture.a = textureSample(u_Specular,u_SpecularSampler, getSpecularUV()).a;
            #endif
            #if ~{def.u_SpecularColor}
                specularTexture.rgb = textureSample(u_SpecularColor,u_SpecularColorSampler, getSpecularColorUV()).rgb;
            #endif
            materialInfo.f0_dielectric = min(materialInfo.f0_dielectric * specularColorFactor * specularTexture.rgb, vec3(1.0));
            materialInfo.specularWeight = specularFactor * specularTexture.a;
            materialInfo.f90_dielectric = vec3(materialInfo.specularWeight);
        #endif
        // TRANSMISSION
        #if ~{def.u_TransmissionFactor}
          materialInfo.transmissionFactor = u_TransmissionFactor;
           #if ~{def.u_Transmission}
                var transmissionSample:vec4<f32> = textureSample(u_Transmission,u_TransmissionSampler, getTransmissionUV());
                materialInfo.transmissionFactor *= transmissionSample.r;
           #endif
           #if ~{def.dispersion}
            materialInfo.dispersion = dispersion;
           #else
            materialInfo.dispersion = 0.0;
           #endif
        #endif
        // VOLUME
        #if ~{def.u_ThicknessFactor}
            materialInfo.thickness = u_ThicknessFactor;
            materialInfo.attenuationColor = u_AttenuationColor;
            materialInfo.attenuationDistance = u_AttenuationDistance;
            #if ~{def.u_ThicknessFactor}
                var thicknessSample:vec4<f32> = textureSample(u_Thickness,u_ThicknessSampler, getThicknessUV());
                materialInfo.thickness *= thicknessSample.g;
            #endif
        #endif
        // IRIDESCENCE
        #if ~{def.u_IridescenceFactor}
            materialInfo.iridescenceFactor = u_IridescenceFactor;
            materialInfo.iridescenceIor = u_IridescenceIor;
            materialInfo.iridescenceThickness = u_IridescenceThicknessMaximum;
            #if ~{def.u_Iridescence}
            materialInfo.iridescenceFactor *= textureSample(u_Iridescence,u_IridescenceSampler, getIridescenceUV()).r;
            #endif
            #if ~{def.u_IridescenceThickness}
            var thicknessSampled = textureSample(u_IridescenceThickness,u_IridescenceThicknessSampler, getIridescenceThicknessUV()).g;
            var thickness = mix(u_IridescenceThicknessMinimum, u_IridescenceThicknessMaximum, thicknessSampled);
            materialInfo.iridescenceThickness = thickness;
            #endif
        #endif
         // ANISOTROPY
        #if ~{def.u_Anisotropy}
              var direction:vec2<f32> = vec2(1.0, 0.0);
              var strengthFactor:f32 = 1.0;
          #if ~{def.u_AnisotropyMap}
              var anisotropySample:vec3<f32> = textureSample(u_AnisotropyMap,u_AnisotropySampler, getAnisotropyUV()).xyz;
              direction = anisotropySample.xy * 2.0 - vec2(1.0);
              strengthFactor = anisotropySample.z;
          #endif
              var directionRotation:vec2<f32> = u_Anisotropy.xy; // cos(theta), sin(theta)
              var rotationMatrix:mat2<f32> = mat2(directionRotation.x, directionRotation.y, -directionRotation.y, directionRotation.x);
              direction = rotationMatrix * direction.xy;
              materialInfo.anisotropicT = mat3(normalInfo.t, normalInfo.b, normalInfo.n) * normalize(vec3(direction, 0.0));
              materialInfo.anisotropicB = cross(normalInfo.ng, materialInfo.anisotropicT);
              materialInfo.anisotropyStrength = clamp(u_Anisotropy.z * strengthFactor, 0.0, 1.0);
        #endif
         // DIFFUSE TRANSMISSION
        #if ~{def.u_DiffuseTransmissionFactor}
        materialInfo.diffuseTransmissionFactor = u_DiffuseTransmissionFactor;
        materialInfo.diffuseTransmissionColorFactor = u_DiffuseTransmissionColorFactor;
          #if ~{def.u_DiffuseTransmission}
          materialInfo.diffuseTransmissionFactor *= textureSample(u_DiffuseTransmission,u_DiffuseTransmissionSampler, getDiffuseTransmissionUV()).a;
          #endif
          #if ~{def.u_DiffuseTransmissionColor}
          materialInfo.diffuseTransmissionColorFactor *= textureSample(u_DiffuseTransmissionColor,u_DiffuseTransmissionColorSampler, getDiffuseTransmissionColorUV()).rgb;
          #endif
        #endif
        
        materialInfo.perceptualRoughness = clamp(materialInfo.perceptualRoughness, 0.0, 1.0);
        materialInfo.metallic = clamp(materialInfo.metallic, 0.0, 1.0);
        materialInfo.alphaRoughness = materialInfo.perceptualRoughness * materialInfo.perceptualRoughness;
        // light
        var f_specular_dielectric = vec3<f32>(0.0);
        var f_specular_metal = vec3<f32>(0.0);
        var f_diffuse = vec3<f32>(0.0);
        var f_dielectric_brdf_ibl = vec3<f32>(0.0);
        var f_metal_brdf_ibl = vec3<f32>(0.0);
        var f_emissive = vec3<f32>(0.0);
        var clearcoat_brdf = vec3<f32>(0.0);
        var f_sheen = vec3<f32>(0.0);
        var f_specular_transmission = vec3<f32>(0.0);
        var f_diffuse_transmission = vec3<f32>(0.0);
    
        var clearcoatFactor = 0.0;
        var clearcoatFresnel = vec3<f32>(0);
    
        var albedoSheenScaling = 1.0;
        var diffuseTransmissionThickness = 1.0;
        // iridescence  
        #if ~{def.u_IridescenceFactor}
          var iridescenceFresnel_dielectric = evalIridescence(1.0, materialInfo.iridescenceIor, NdotV, materialInfo.iridescenceThickness, materialInfo.f0_dielectric);
          var iridescenceFresnel_metallic = evalIridescence(1.0, materialInfo.iridescenceIor, NdotV, materialInfo.iridescenceThickness, materialInfo.baseColor);
      
          if (materialInfo.iridescenceThickness == 0.0) {
              materialInfo.iridescenceFactor = 0.0;
          }
        #endif
        // diffuse transmission
        #if ~{def.u_DiffuseTransmissionFactor}
          #if ~{def.u_ThicknessFactor}
            diffuseTransmissionThickness = materialInfo.thickness 
          #endif
        #endif
        // CLEARCOAT
        #if ~{def.u_ClearcoatFactor}
          clearcoatFactor = materialInfo.clearcoatFactor;
          clearcoatFresnel = F_SchlickVec3_F09(materialInfo.clearcoatF0, materialInfo.clearcoatF90, clampedDot(materialInfo.clearcoatNormal, v));
        #endif
        // 
        // ibl
        #if ~{def.brdfLUT && def.prefilterMap && def.irradianceMap}
           f_diffuse = getDiffuseLight(-n) * materialInfo.baseColor ;
          // diffuse transmission
           #if ~{def.u_DiffuseTransmissionFactor}
            var diffuseTransmissionIBL:vec3<f32> = getDiffuseLight(-n) * materialInfo.diffuseTransmissionColorFactor;
            #if ~{def.u_ThicknessFactor}
              diffuseTransmissionIBL = applyVolumeAttenuation(diffuseTransmissionIBL, diffuseTransmissionThickness, materialInfo.attenuationColor, materialInfo.attenuationDistance);
            #endif
            f_diffuse = mix(f_diffuse, diffuseTransmissionIBL, materialInfo.diffuseTransmissionFactor);
           #endif
          // transmission
           #if ~{def.u_TransmissionFactor}
          //  需要u_ModelMatrix、u_ViewMatrix、u_ProjectionMatrix 未实现
           #endif
          // anisotropy
           #if ~{def.u_Anisotropy}
           f_specular_metal = getIBLRadianceAnisotropy(n, v, materialInfo.perceptualRoughness, materialInfo.anisotropyStrength, materialInfo.anisotropicB);
           f_specular_dielectric = f_specular_metal;
          #else
           f_specular_metal = getIBLRadianceGGX(n, v, materialInfo.perceptualRoughness);
           f_specular_dielectric = f_specular_metal;
          #endif
          var f_metal_fresnel_ibl:vec3<f32> = getIBLGGXFresnel(n, v, materialInfo.perceptualRoughness, materialInfo.baseColor, 1.0);
          f_metal_brdf_ibl = f_metal_fresnel_ibl * f_specular_metal;
        
          var f_dielectric_fresnel_ibl:vec3<f32> = getIBLGGXFresnel(n, v, materialInfo.perceptualRoughness, materialInfo.f0_dielectric, materialInfo.specularWeight);
          f_dielectric_brdf_ibl = mix(f_diffuse, f_specular_dielectric,  f_dielectric_fresnel_ibl);
          #if ~{def.u_IridescenceFactor}
              f_metal_brdf_ibl = mix(f_metal_brdf_ibl, f_specular_metal * iridescenceFresnel_metallic, materialInfo.iridescenceFactor);
              f_dielectric_brdf_ibl = mix(f_dielectric_brdf_ibl, rgb_mix(f_diffuse, f_specular_dielectric, iridescenceFresnel_dielectric), materialInfo.iridescenceFactor);
          #endif
          #if ~{def.u_ClearcoatFactor}
            clearcoat_brdf = getIBLRadianceGGX(materialInfo.clearcoatNormal, v, materialInfo.clearcoatRoughness);
          #endif
          #if ~{def.u_SheenColorFactor}
              f_sheen = getIBLRadianceCharlie(n, v, materialInfo.sheenRoughnessFactor, materialInfo.sheenColorFactor);
              albedoSheenScaling = 1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotV, materialInfo.sheenRoughnessFactor);
          #endif
          color = mix(f_dielectric_brdf_ibl, f_metal_brdf_ibl, materialInfo.metallic);
          color = f_sheen + color * albedoSheenScaling;
          color = mix(color, clearcoat_brdf, clearcoatFactor * clearcoatFresnel);
          #if ~{def.aoMap}
              var ao = 1.0;
              ao = textureSample(aoMap,aoMap_sampler,  getOcclusionUV(input)).r;
              color = color * (1.0 +  (ao - 1.0)); 
          #endif
        #endif
     
        f_diffuse = vec3(0.0);
        f_specular_dielectric = vec3(0.0);
        f_specular_metal = vec3(0.0);
        var f_dielectric_brdf = vec3(0.0);
        var f_metal_brdf = vec3(0.0);
      //  cesi
      var pointShadowCount:u32=0;
      #if ~{def.punctualLight}
        for (var i: i32 = 0; i < punctualCount; i++){
          var light=punctusLight.lights[i];
          var pointToLight:vec3<f32>;
          if (light.t ==3.0 || light.t==4.0){
            pointToLight = light.position-light.at;
          }else{
            pointToLight = light.position - input.fragPosition;
          }
          if(light.t==4.0){ //面光源计算是否在范围内
            var flag:bool=input.fragPosition[0]>=light.position[0]-light.e1/2&&input.fragPosition[0]<=light.position[0]+light.e1/2&&input.fragPosition[1]>=light.position[1]-light.e2/2&&input.fragPosition[1]<=light.position[1]+light.e2/2;
            if(flag == false){
              continue;
              }
          }
          var l:vec3<f32> = normalize(pointToLight);
          var h:vec3<f32> = normalize(l + v); 
          var NdotL:f32 =max(0.0001,clampedDot(n, l)) ;
          var NdotH:f32 =max(0.0001, clampedDot(n, h));
          var LdotH:f32 =max(0.0001, clampedDot(l, h));
          var VdotH:f32 =max(0.0001, clampedDot(v, h)); 
          var dielectric_fresnel = F_SchlickVec3_F09(materialInfo.f0_dielectric * materialInfo.specularWeight, materialInfo.f90_dielectric, abs(VdotH));
          var metal_fresnel = F_SchlickVec3_F09(materialInfo.baseColor, vec3(1.0), abs(VdotH));
          var lightIntensity = getLighIntensity(light, pointToLight);
          #if ~{def.lightCastCount}
          if(light.e1==1.0){//castShadow
            if(light.t==1.0){//如果是点光源
              #if ~{def.pointShadow}
                pointShadowCount++;
                var shadowFactor = calculateShadowPoint(light,input,light.e2,pointShadowCount,n); 
                lightIntensity=lightIntensity*(1.0 - shadowFactor);
              #endif
            }else{
              #if ~{def.ShadowMap}
                var bias = max(light.e2 * (1.0 - NdotL), light.e2);//shadowBias:e2
                var shadowFactor= calculateShadow(light,input,bias,i);
                lightIntensity=lightIntensity*shadowFactor;
              #endif
            }
          }
          #endif
          var l_diffuse = lightIntensity * NdotL * BRDF_lambertian(materialInfo.baseColor);
          var l_specular_dielectric = vec3(0.0);
          var l_specular_metal = vec3(0.0);
          var l_dielectric_brdf = vec3(0.0);
          var l_metal_brdf = vec3(0.0);
          var l_clearcoat_brdf = vec3(0.0);
          var l_sheen = vec3(0.0);
          var l_albedoSheenScaling = 1.0;
          // DIFFUSE_TRANSMISSION
          #if ~{def.u_DiffuseTransmissionFactor}
          var diffuse_btdf = lightIntensity * clampedDot(-n, l) * BRDF_lambertian(materialInfo.diffuseTransmissionColorFactor);
            #if ~{def.u_ThicknessFactor}
                diffuse_btdf = applyVolumeAttenuation(diffuse_btdf, diffuseTransmissionThickness, materialInfo.attenuationColor, materialInfo.attenuationDistance);
            #endif
          l_diffuse = mix(l_diffuse, diffuse_btdf, materialInfo.diffuseTransmissionFactor);
          #endif 
          // TRANSMISSION
          #if ~{def.u_TransmissionFactor}
          //  需要u_ModelMatrix、u_ViewMatrix、u_ProjectionMatrix 未实现
          #endif
          // ANISOTROPY
          #if ~{def.u_Anisotropy}
          l_specular_metal = lightIntensity * NdotL * BRDF_specularGGXAnisotropy(materialInfo.alphaRoughness, materialInfo.anisotropyStrength, n, v, l, h, materialInfo.anisotropicT, materialInfo.anisotropicB);
          l_specular_dielectric = l_specular_metal;
          #else
          l_specular_metal = lightIntensity * NdotL * BRDF_specularGGX(materialInfo.alphaRoughness, NdotL, NdotV, NdotH);
          l_specular_dielectric = l_specular_metal;
          #endif
          l_metal_brdf = metal_fresnel * l_specular_metal;
          l_dielectric_brdf = mix(l_diffuse, l_specular_dielectric, dielectric_fresnel);
          // IRIDESCENCE
          #if ~{def.u_IridescenceFactor}
          l_metal_brdf = mix(l_metal_brdf, l_specular_metal * iridescenceFresnel_metallic, materialInfo.iridescenceFactor);
          l_dielectric_brdf = mix(l_dielectric_brdf, rgb_mix(l_diffuse, l_specular_dielectric, iridescenceFresnel_dielectric), materialInfo.iridescenceFactor);
          #endif
          // CLEARCOAT
          #if ~{def.u_ClearcoatFactor}
          l_clearcoat_brdf = lightIntensity * getPunctualRadianceClearCoat(materialInfo.clearcoatNormal, v, l, h, VdotH,
              materialInfo.clearcoatF0, materialInfo.clearcoatF90, materialInfo.clearcoatRoughness);
          #endif
          // SHEEN
          #if ~{def.u_SheenColorFactor}
          l_sheen = lightIntensity * getPunctualRadianceSheen(materialInfo.sheenColorFactor, materialInfo.sheenRoughnessFactor, NdotL, NdotV, NdotH);
          l_albedoSheenScaling = min(1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotV, materialInfo.sheenRoughnessFactor),
              1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotL, materialInfo.sheenRoughnessFactor));
          #endif
          var l_color = mix(l_dielectric_brdf, l_metal_brdf, materialInfo.metallic);
          l_color = l_sheen + l_color * l_albedoSheenScaling;
          l_color = mix(l_color, l_clearcoat_brdf, clearcoatFactor * clearcoatFresnel);
          color += l_color;
        }
        #endif
        f_emissive = baseMaterial.emissive;
        #if ~{def.u_EmissiveStrength}
         f_emissive *= u_EmissiveStrength;
        #endif
        #if ~{def.emissiveMap}
          f_emissive *= textureSample(emissiveMap,emissiveMap_sampler, getEmissiveUV(input)).rgb;
        #endif
        color = f_emissive * (1.0 - clearcoatFactor * clearcoatFresnel) + color;
        color = color+cal_ambientLight(input) ;
       
        #if ~{def.ColorAdjust}
          if(colorAdjust.ToneMapping==1.0){
            color=LinearToneMapping(color);
          }else if(colorAdjust.ToneMapping==2.0){
            color=ReinhardToneMapping(color);
          }else if(colorAdjust.ToneMapping==3.0){
            color=OptimizedCineonToneMapping(color);
          }else if(colorAdjust.ToneMapping==4.0){
            color=RRTAndODTFit(color);
          }else if(colorAdjust.ToneMapping==5.0){
            color=ACESFilmicToneMapping(color);
          }else{
            color=CustomToneMapping(color);
          }
        #endif
        color=linearToSRGB(color,vec3(GAMM));
        output.color=vec4<f32>(color,material.color.a*baseMaterial.opacity);
        #if ~{def.gBuffer}
         output.worldPos = vec4<f32>(input.fragPosition.xyz,1.0);
         output.worldNormal = vec4<f32>(n,1.0);
        #endif
        // output.color=vec4(dep,dep,dep,1.0);
        // output.color=colorXYZ;
        // output.color= vec4<f32>(input.fragPosition.xyz,1.0);
        // output.color=vec4(dep,dep,dep,1.0);
        // output.color=vec4<f32>(color*visibility,material.color.a*baseMaterial.opacity);
        // output.color=vec4<f32>(shadowPos1.xy,1.0,material.color.a*baseMaterial.opacity);
        // output.color=vec4<f32>(closestDepth1);
        // output.color=vec4<f32>(f32(punctualCount));
        #if ~{def.logarithmicDepth}
        output.fragDepth = log2(input.flogz ) * ~{def.logarithmicDepth} * 0.5;
        #endif
       
        return output;
    }
    `;
export { StandardMaterial };